package org.sction.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Clob;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletRequest;

public class StringUtils {
	public static String defEncode = "UTF-8";

	public static String UUID() {
		return java.util.UUID.randomUUID().toString();
	}

	public static boolean isEmpty(Object obj) {
		if (obj == null) {
			return true;
		} else if (obj instanceof java.lang.String) {
			return obj.toString().trim().length() == 0;
		} else if (obj instanceof java.util.Collection<?>) {
			return ((java.util.Collection<?>) obj).isEmpty();
		} else if (obj instanceof java.util.Map<?, ?>) {
			return ((java.util.Map<?, ?>) obj).isEmpty();
		} else if (obj instanceof java.util.Iterator<?>) {
			return ((java.util.Iterator<?>) obj).hasNext();
		} else if (obj instanceof java.util.Enumeration<?>) {
			return ((java.util.Enumeration<?>) obj).hasMoreElements();
		} else {
			return false;
		}
	}

	public static boolean isNotEmpty(Object str) {
		return !isEmpty(str);
	}

	public static Object emptyConvert(Object str, Object str1) {
		return isEmpty(str) ? str1 : str;
	}

	public static String emptyConvert(Object str, String str1) {
		return isEmpty(str) ? str1 : str.toString();
	}

	public static String emptyConvert(String str, String str1) {
		return isEmpty(str) ? str1 : str;
	}

	public static String trim(String str) {
		return str == null ? null : str.trim();
	}

	public static String replaceOnce(String text, String searchString,
			String replacement) {
		return replace(text, searchString, replacement, 1);
	}

	public static String replace(String text, String searchString,
			String replacement) {
		return replace(text, searchString, replacement, -1);
	}

	public static String replace(String text, String searchString,
			String replacement, int max) {
		if (isEmpty(text) || isEmpty(searchString) || replacement == null
				|| max == 0) {
			return text;
		}
		int start = 0;
		int end = text.indexOf(searchString, start);
		if (end == -1) {
			return text;
		}
		int replLength = searchString.length();
		int increase = replacement.length() - replLength;
		increase = (increase < 0 ? 0 : increase);
		increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
		StringBuffer buf = new StringBuffer(text.length() + increase);
		while (end != -1) {
			buf.append(text.substring(start, end)).append(replacement);
			start = end + replLength;
			if (--max == 0) {
				break;
			}
			end = text.indexOf(searchString, start);
		}
		buf.append(text.substring(start));
		return buf.toString();
	}

	public static boolean startsWith(String str, String prefix) {
		return startsWith(str, prefix, false);
	}

	public static boolean startsWithIgnoreCase(String str, String prefix) {
		return startsWith(str, prefix, true);
	}

	public static boolean startsWith(String str, String prefix,
			boolean ignoreCase) {
		return startsOrEndsWith(str, prefix, ignoreCase, false);
	}

	public static boolean endsWith(String str, String suffix) {
		return endsWith(str, suffix, false);
	}

	public static boolean endsWithIgnoreCase(String str, String suffix) {
		return endsWith(str, suffix, true);
	}

	public static boolean endsWith(String str, String prefix, boolean ignoreCase) {
		return startsOrEndsWith(str, prefix, ignoreCase, true);
	}

	private static boolean startsOrEndsWith(String str, String subStr,
			boolean ignoreCase, boolean endWidth) {
		if (str == null || subStr == null) {
			return (str == null && subStr == null);
		}
		if (subStr.length() > str.length()) {
			return false;
		}
		int strOffset = 0;
		if (endWidth) {
			strOffset = str.length() - subStr.length();
		}
		return str.regionMatches(ignoreCase, strOffset, subStr, 0,
				subStr.length());
	}

	public static final String EMPTY = "";

	public static String join(String[] array) {
		return join(array, null);
	}

	public static String join(String[] list, String separator) {
		separator = separator == null ? EMPTY : separator;
		StringBuffer buff = new StringBuffer(5 * list.length);
		for (int i = 0; i < list.length; i++) {
			String s = list[i];
			if (i > 0) {
				buff.append(separator);
			}
			if (s != null) {
				buff.append(s);
			}
		}
		return buff.toString();

	}

	public static String[] split2Array(String s, char separatorChar) {
		return split2Array(s, separatorChar, false);
	}

	public static String[] split2Array(String s, char separatorChar,
			boolean trim) {
		if (s == null) {
			return null;
		}
		if (s.length() == 0) {
			return new String[0];
		}
		ArrayList<String> list = new ArrayList<String>();
		StringBuffer buff = new StringBuffer(s.length());
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			if (c == separatorChar) {
				String e = buff.toString();
				list.add(trim ? e.trim() : e);
				buff.setLength(0);
			} else if (c == '\\' && i < s.length() - 1) {
				buff.append(s.charAt(++i));
			} else {
				buff.append(c);
			}
		}
		String e = buff.toString();
		list.add(trim ? e.trim() : e);
		String[] array = new String[list.size()];
		list.toArray(array);
		return array;
	}

	/**
	 * 字符串转换成十六进制字符串
	 */

	public static String str2HexStr(String str) {

		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
		}
		return sb.toString();
	}

	/**
	 * 
	 * 十六进制转换字符串
	 */

	public static String hexStr2Str(String hexStr) {
		String str = "0123456789ABCDEF";
		char[] hexs = hexStr.toCharArray();
		byte[] bytes = new byte[hexStr.length() / 2];
		int n;
		for (int i = 0; i < bytes.length; i++) {
			n = str.indexOf(hexs[2 * i]) * 16;
			n += str.indexOf(hexs[2 * i + 1]);
			bytes[i] = (byte) (n & 0xff);
		}
		return new String(bytes);
	}

	/**
	 * bytes转换成十六进制字符串
	 */
	public static String byte2HexStr(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
			// if (n<b.length-1) hs=hs+":";
		}
		return hs.toUpperCase();
	}

	private static byte uniteBytes(String src0, String src1) {
		byte b0 = Byte.decode("0x" + src0).byteValue();
		b0 = (byte) (b0 << 4);
		byte b1 = Byte.decode("0x" + src1).byteValue();
		byte ret = (byte) (b0 | b1);
		return ret;
	}

	/**
	 * bytes转换成十六进制字符串
	 */
	public static byte[] hexStr2Bytes(String src) {
		int m = 0, n = 0;
		int l = src.length() / 2;
		byte[] ret = new byte[l];
		for (int i = 0; i < l; i++) {
			m = i * 2 + 1;
			n = m + 1;
			ret[i] = uniteBytes(src.substring(i * 2, m), src.substring(m, n));
		}
		return ret;
	}

	/**
	 * String的字符串转换成unicode的String
	 */
	public static String str2Unicode(String strText) throws Exception {
		char c;
		String strRet = "";
		int intAsc;
		String strHex;
		for (int i = 0; i < strText.length(); i++) {
			c = strText.charAt(i);
			intAsc = (int) c;
			strHex = Integer.toHexString(intAsc);
			if (intAsc > 128) {
				strRet += "\\u" + strHex;
			} else {
				// 低位在前面补00
				strRet += "\\u00" + strHex;
			}
		}
		return strRet;
	}

	/**
	 * unicode的String转换成String的字符串
	 */
	public static String unicode2Str(String hex) {
		int t = hex.length() / 6;
		StringBuilder str = new StringBuilder();
		for (int i = 0; i < t; i++) {
			String s = hex.substring(i * 6, (i + 1) * 6);
			// 高位需要补上00再转
			String s1 = s.substring(2, 4) + "00";
			// 低位直接转
			String s2 = s.substring(4);
			// 将16进制的string转为int
			int n = Integer.valueOf(s1, 16) + Integer.valueOf(s2, 16);
			// 将int转换为字符
			char[] chars = Character.toChars(n);
			str.append(new String(chars));
		}
		return str.toString();
	}

	public static String clobToString(Clob c) {
		BufferedReader in = null;
		try {
			in = new BufferedReader(c.getCharacterStream());

			StringWriter out = new StringWriter();
			int i;
			while ((i = in.read()) != -1) {
				out.write(i);
			}
			return out.toString();
		} catch (Exception e) {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e1) {
				}
			}
		}
		return "";
	}

	public static String encode(String str, String encode)
			throws UnsupportedEncodingException {
		String encoding = getEncoding(str);
		if (isNotEmpty(encode)) {
			str = new String(str.getBytes(encoding), encode);
		}
		return str;
	}

	public static String encode(String str) throws UnsupportedEncodingException {
		if (isNotEmpty(defEncode)) {
			String encoding = getEncoding(str);
			str = new String(str.getBytes(encoding), defEncode);
		}
		return str;
	}

	public static String getEncoding(String str) {
		String encode = "GB2312";
		try {
			if (str.equals(new String(str.getBytes(encode), encode))) {
				String s = encode;
				return s;
			}
		} catch (Exception exception) {
		}
		encode = "ISO-8859-1";
		try {
			if (str.equals(new String(str.getBytes(encode), encode))) {
				String s1 = encode;
				return s1;
			}
		} catch (Exception exception1) {
		}
		encode = "UTF-8";
		try {
			if (str.equals(new String(str.getBytes(encode), encode))) {
				String s2 = encode;
				return s2;
			}
		} catch (Exception exception2) {
		}
		encode = "GBK";
		try {
			if (str.equals(new String(str.getBytes(encode), encode))) {
				String s3 = encode;
				return s3;
			}
		} catch (Exception exception3) {
		}
		return "";
	}

	public static List<String> findAll(String str, String regex) {
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		List<String> list = new ArrayList<String>();
		while (matcher.find()) {
			list.add(matcher.group());
		}
		return list;
	}

	public static String find(String str, String regex) {
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		if (matcher.find()) {
			return matcher.group();
		}
		return "";
	}

	public static String getRequestParamsString(ServletRequest request) {
		@SuppressWarnings("unchecked")
		Map<String, String[]> map = request.getParameterMap();
		String urlParams = null;
		if (map != null) {
			urlParams = "";
			for (Iterator<String> iterator = map.keySet().iterator(); iterator
					.hasNext();) {
				String key = iterator.next();
				String[] s = map.get(key);
				for (int i = 0; i < s.length; i++) {
					if (i < (s.length - 1) || iterator.hasNext()) {
						urlParams += key + "=" + s[i] + "&";
					} else {
						urlParams += key + "=" + s[i];
					}
				}
			}
		}
		return urlParams;
	}

	public static String getMd5(String str) throws NoSuchAlgorithmException {

		final MessageDigest md = MessageDigest.getInstance("MD5");
		md.update(str.getBytes());
		final byte b[] = md.digest();
		int i;
		final StringBuffer buf = new StringBuffer("");
		for (int offset = 0; offset < b.length; offset++) {
			i = b[offset];
			if (i < 0) {
				i += 256;
			}
			if (i < 16) {
				buf.append("0");
			}
			buf.append(Integer.toHexString(i));
		}
		return buf.toString();
	}

	public static String toMd5(String str) throws UnsupportedEncodingException,
			NoSuchAlgorithmException {
		MessageDigest messageDigest = null;
		messageDigest = MessageDigest.getInstance("MD5");
		messageDigest.reset();
		messageDigest.update(str.getBytes("UTF-8"));

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();
		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(
						Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}

		return md5StrBuff.toString();
	}

	public static String arryToString(Object obj) {

		if (obj == null) {
			return null;
		} else {
			if (obj.getClass().isArray()) {
				String result = "";
				Object[] objs = (Object[]) obj;
				result += "[";
				for (int i = 0; i < objs.length; i++) {
					Object object = objs[i];
					if (i != 0) {
						result += ", ";
					}
					if (object == null) {
						result += object;
					} else if (object.getClass().isArray()) {
						result += arryToString(object);
					} else {
						result += object;
					}
				}
				result += "]";
				return result;
			} else {
				return obj.toString();
			}

		}

	}

	public static String runConsoleCommand(String command) throws IOException {
		Process p = Runtime.getRuntime().exec(command);
		if (p != null) {
			InputStream stdoutStream = new BufferedInputStream(
					p.getInputStream());
			StringBuffer buffer = new StringBuffer();

			while (true) {
				int c = stdoutStream.read();
				if (c == -1) {
					break;
				}
				buffer.append((char) c);
			}
			String outputText = buffer.toString();
			stdoutStream.close();
			p.destroy();
			return outputText;
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public static <T> T StringCast(String value, Class<T> clazz)
			throws ParseException, NumberFormatException, ClassCastException {
		try {
			Object obj = value;
			if (clazz.equals(Integer.class) || clazz.equals(int.class)) {
				obj = Integer.parseInt(value);
			} else if (clazz.equals(Boolean.class)
					|| clazz.equals(boolean.class)) {
				obj = Boolean.parseBoolean(value);
			} else if (clazz.equals(Float.class) || clazz.equals(float.class)) {
				obj = Float.parseFloat(value);
			} else if (clazz.equals(Double.class) || clazz.equals(double.class)) {
				obj = Double.parseDouble(value);
			} else if (clazz.equals(Long.class) || clazz.equals(long.class)) {
				obj = Long.parseLong(value);
			} else if (clazz.equals(Date.class)) {
				obj = DateUtils.StringAutoCast(value);
			} else if (clazz.equals(java.sql.Date.class)) {
				obj = new java.sql.Date(DateUtils.StringAutoCast(value)
						.getTime());
			} else if (clazz.equals(java.sql.Timestamp.class)) {
				obj = new java.sql.Timestamp(DateUtils.StringAutoCast(value)
						.getTime());
			}
			return (T) obj;
		} catch (NumberFormatException e) {
			throw e;
		} catch (ParseException e) {
			throw e;
		} catch (ClassCastException e) {
			throw e;
		}
	}

	public static Set<String> toSet(String data) {
		Set<String> set = new HashSet<String>();
		if (data != null) {
			data = data.trim();
			if (data.startsWith("[")) {
				data = data.substring(1, data.length());
			}
			if (data.endsWith("]")) {
				data = data.substring(0, data.length() - 1);
			}
			return toSet(data, ",");
		}
		return set;
	}

	public static Set<String> toSet(String data, String split) {
		Set<String> set = new HashSet<String>();
		if (data != null) {
			String[] datas = data.split(split);
			for (String str : datas) {
				set.add(str);
			}
		}
		return set;
	}

	public static String setToString(Set<String> data) {
		String result = "";
		if (data != null) {
			Iterator<String> it = data.iterator();
			for (int i = 0; it.hasNext(); i++) {
				result += ((i == 0 ? "" : ",") + it.next());
			}
		}
		return result;
	}

	public static Map<String, Object> toMap(String data) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (data != null) {
			data = data.trim();
			if (data.startsWith("{")) {
				data = data.substring(1, data.length());
			}
			if (data.endsWith("}")) {
				data = data.substring(0, data.length() - 1);
			}
			String[] dts = data.split(",");
			for (int i = 0; i < dts.length; i++) {
				String dt = dts[i].trim();
				String[] kds;
				if (dt.split("=").length == 2) {
					kds = dt.split("=");
				} else if (dt.split(":").length == 2) {
					kds = dt.split(":");
				} else {
					kds = null;
				}
				if (kds != null) {
					map.put(kds[0], kds[1]);
				}

			}
		}
		return map;
	}

	public static void main(String[] args) {
	}

}
